#include "rtmp_publish_message.hpp"
#include "server/rtmp/rtmp_message/rtmp_message.hpp"
using namespace mms;
RtmpPublishMessage::RtmpPublishMessage()
{
}

RtmpPublishMessage::RtmpPublishMessage(int32_t transaction_id, const std::string &stream_name, const std::string &pub_type)
{
    command_name_.set_value("publish");
    transaction_id_.set_value(transaction_id);
    stream_name_.set_value(stream_name);
    publish_type_.set_value(pub_type);
}

RtmpPublishMessage::~RtmpPublishMessage()
{
}

int32_t RtmpPublishMessage::decode(std::shared_ptr<RtmpMessage> rtmp_msg)
{
    int32_t consumed = 0;
    int32_t pos = 0;
    const uint8_t *payload = rtmp_msg->payload_;
    int32_t len = rtmp_msg->payload_size_;
    consumed = command_name_.decode(payload, len);
    if (consumed < 0)
    {
        return -1;
    }
    pos += consumed;
    payload += consumed;
    len -= consumed;

    consumed = transaction_id_.decode(payload, len);
    if (consumed < 0)
    {
        return -2;
    }
    pos += consumed;
    payload += consumed;
    len -= consumed;

    consumed = command_obj_.decode(payload, len);
    if (consumed < 0)
    {
        consumed = null_.decode(payload, len);
        if (consumed < 0)
        {
            return -4;
        }
    }
    pos += consumed;
    payload += consumed;
    len -= consumed;

    consumed = stream_name_.decode(payload, len);
    if (consumed < 0)
    {
        return -5;
    }
    pos += consumed;
    payload += consumed;
    len -= consumed;

    consumed = publish_type_.decode(payload, len);
    if (consumed < 0)
    {
        return -6;
    }
    pos += consumed;
    payload += consumed;
    len -= consumed;
    return pos;
}

const std::string &RtmpPublishMessage::stream_name() const
{
    return stream_name_.get_value();
}

int32_t RtmpPublishMessage::size()
{
    int32_t size = 0;
    size += command_name_.size();
    size += transaction_id_.size();
    size += command_obj_.size();
    size += stream_name_.size();
    size += publish_type_.size();
    return size;
}

std::shared_ptr<RtmpMessage> RtmpPublishMessage::encode()
{
    auto need_size = size();
    std::shared_ptr<RtmpMessage> rtmp_msg = std::make_shared<RtmpMessage>(need_size);
    rtmp_msg->chunk_stream_id_ = RTMP_CHUNK_ID_COMMAND_MESSAGE; // RTMP_CHUNK_ID_PROTOCOL_CONTROL_MESSAGE;
    rtmp_msg->timestamp_ = 0;
    rtmp_msg->message_type_id_ = RTMP_MESSAGE_TYPE_AMF0_COMMAND;
    rtmp_msg->message_strean_id_ = RTMP_MESSAGE_ID_PROTOCOL_CONTROL;

    int32_t consumed = 0;
    int32_t pos = 0;
    uint8_t *payload = rtmp_msg->payload_;
    int32_t len = need_size;
    consumed = command_name_.encode(payload, len);
    if (consumed < 0)
    {
        return nullptr;
    }
    pos += consumed;
    payload += consumed;
    len -= consumed;

    consumed = transaction_id_.encode(payload, len);
    if (consumed < 0)
    {
        return nullptr;
    }
    pos += consumed;
    payload += consumed;
    len -= consumed;

    consumed = command_obj_.encode(payload, len);
    if (consumed < 0)
    {
        return nullptr;
    }
    pos += consumed;
    payload += consumed;
    len -= consumed;

    consumed = stream_name_.encode(payload, len);
    if (consumed < 0)
    {
        return nullptr;
    }
    pos += consumed;
    payload += consumed;
    len -= consumed;

    consumed = publish_type_.encode(payload, len);
    if (consumed < 0)
    {
        return nullptr;
    }
    pos += consumed;
    payload += consumed;
    len -= consumed;
    rtmp_msg->payload_size_ = pos;
    return rtmp_msg;
}
